/*
Author: Monica
Purpose: Creates the player entity and contains everything that involves the player in the game(animation, collision detection etc)
Modified: Matrix (robot animation)
*/


#pragma once

#include "../../nclgl/Mesh.h"
#include "../nclgl/CubeRobot.h"
#include "GameEntity.h"
#include "Subject.h"
#include "ChunckManager.h"
#include "TerrainClass.h"
#include "XBOXController.h"
#include "../nclgl/ControllerHeader.h"
#include"Animation.h"
#include"Renderer.h"
#include "SpringNode.h"
#include "PhysicsSystem.h"

#define MAX_RUSH_TIME 400
#define RUSH_VELOCITY_INCREASE -0.3f
#define LINEAR_VELOCITY_TERRIAN_INCREASE -0.1f
#define MAX_FLY_TIME 600
#define LINEAR_VELOCITY_GRASS -0.3f
#define LINEAR_VELOCITY_BARE_GROUND -0.4f
#define LINEAR_VELOCITY_ROCK -0.1f
#define LINEAR_VELOCITY_SAND  -0.2f

class PlayerClass {
public:
	PlayerClass();
	~PlayerClass();

	// ------ Added by Monica ---------- //
	void UpdatePlayer(float msec);

	int getPlayerId() const { return playerId; }
	void setPlayerId(int id) { playerId = id; }

	float getAmountHorizontaLinearVelocity() const { return amountHorizontalLinearVelocity; }
	void setAmountHorizontalLinearVelocity(float nr) { amountHorizontalLinearVelocity = nr; }

	float getAmountMovementOnZAxis() const { return amountMovementZ; }

	Vector3 getPlayerCoordinatesVoxel() const { return playerCoordinatesVoxel; }
	void setPlayerCoordinatesVoxel(Vector3 vect) { playerCoordinatesVoxel = vect; }

	bool setPlayerVoxelCoordinates(Vector3 position);
	Vector3 getPlayerCoordinatesFromVoxel(bool left, bool right);

	GameEntity* getPlayerEntity() const { return playerEntity; }
	PhysicsNode* getPlayerPhysicsNode() const { return physicsNodePlayer; }

	static bool getGoLeft() { return GO_LEFT; }
	static bool getGoRight() { return GO_RIGHT; }
	static bool getjump() { return JUMP; }
	static bool getHasCollidedForObjects() { return HAS_COLLIDED_FOR_OBJECTS; }
	static bool getHasCollidedWithTree() { return HAS_COLLIDED_WITH_TREE; }
	static Vector3 getVelocityTerrain() { return VELOCITY_TERRAIN; }

	void setTerrainEntity(TerrainClass* terr) { terrain = terr; }
	void resetPlayerOnTerrain(Vector3 position, float scale);
	void checkPlayerOnTerrainBounds(Vector3 position);

	void detectAndResolveCollisionsWithTerrain();
	// -------------------------------------- //

	//added by Borja
	Subject* getSubject() { return playerSubject; }

	int	getHealth() { return health; }
	//--------------

	// ------------- //
	//added by Matrix
	// Robot animation //
	void RobotAnimation(char Move, GameEntity* robot);
	void StopAnimation(GameEntity* robot);
	void Jump(GameEntity* robot);
	void LeftTurn(GameEntity* robot);
	void RightTurn(GameEntity* robot);
	void StraightAhead(GameEntity* robot);
	void Fly(PhysicsNode*player);
	void MoveUp(GameEntity* robot);
	void MoveDown(GameEntity* robot);
	void MoveBack(GameEntity* robot);
	
	void SetSceneRush(bool isRush){ Isrush = isRush; } //the scene will move fastly when player rush
	//-------------//

	void Buff();
	void Debuff();

	void BuildRobotEntity();

	void SetStateInCubeRobot(int state);

	static Vector3 PLAYER_POSITION;

	XBOXController* GetXboxController() { return &controller; }

private:
	//-------  Added by Monica ------- //
	int playerId;
	float amountHorizontalLinearVelocity;
	float amountMovementZ;
	Vector3 playerCoordinatesVoxel;

	GameEntity* playerEntity;
	PhysicsNode* physicsNodePlayer;
	CubeRobot*   renderNodePlayer;
	TerrainClass* terrain;

	static bool GO_LEFT;
	static bool GO_RIGHT;
	static bool JUMP;
	static bool HAS_COLLIDED_WITH_TREE;
	static Vector3 VELOCITY_TERRAIN;
	//this is a boolean for the spawned objects
	static bool HAS_COLLIDED_FOR_OBJECTS;
	bool isVelocityFalse;
	bool debug;


	// --- Private methods for collision detection --- //
	void resetTerrainVelocity();
	void positionPlayerOnTerrain();
	Vector3 updatePlayersMovementOnTerrain();

	bool checkAndResolvePlayerCollisionOnYAxis(Vector3 playerPosition, Vector3 position, Vector3 velocity);
	bool checkAndResolvePlayerCollisionOnXAxisLeft(Vector3 playerPosition, Vector3 position, Vector3 velocity);
	bool checkAndResolvePlayerCollisionOnXAxisRight(Vector3 playerPosition, Vector3 position, Vector3 velocity);
	void checkAndResolvePlayerCollisionOnZAxis(Vector3 playerPosition, Vector3 terrainPosition);
	// -------------------------------- //

	//added by Borja
	Subject* playerSubject;
	int health;
	XBOXController controller;
	//--------------



	//added by Matrix
	Animation* animation;
	int  flyTime;
	int  rushTime;
	static bool Isfly;
	bool Isrush;
	//Camera* CameraToPlayer;
	
};